//Listing 3. Simple Sound Playback
 
/*This example reads standard from input and writesto the default PCM device for 5 seconds of data.*/
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <speex/speex.h>
#include <alsa/asoundlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BIND_PORT 12345
//#define TO_ADDR "192.168.2.233"

/*The frame size in hardcoded for this sample code but it doesn't have to be*/
#define FRAME_SIZE 160

struct sockaddr_in addr;
int fd;
int len;

/*Holds the audio that will be written to file (16 bits per sample)*/
short out[FRAME_SIZE];
/*Speex handle samples as float, so we need an array of floats*/
float output[FRAME_SIZE];
char cbits[200];
int nbBytes;
/*Holds the state of the decoder*/
void *state;
/*Holds bits so they can be read and written to by the Speex routines*/
SpeexBits bits;
int i, tmp;
   
void init_udp()
{
 printf("init_udp 1111111111111111111\n");
     /* create what looks like an ordinary UDP socket */
     if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) 
     {
				perror("socket");
				exit(1);
     }
 printf("init_udp 3333333\n");
     /* set up destination address */
     memset(&addr,0,sizeof(addr));
 printf("init_udp 44444444\n");     
     addr.sin_family=AF_INET;
     addr.sin_addr.s_addr=htonl(INADDR_ANY);
     addr.sin_port=htons(BIND_PORT);
      printf("init_udp 5555555\n");
  	if(bind ( fd, &addr, sizeof(addr))==-1)
		printf("error\n");
	else
		printf("ok\n");    
		 printf("init_udp 999999999\n");
	len =  sizeof(addr);
}

int main() 
{ 
long loops; 
int rc; 
int size; 
snd_pcm_t *handle; 
snd_pcm_hw_params_t *params; 
unsigned int val; 
int dir; 
snd_pcm_uframes_t frames; 
char *buffer; 
 
 printf("1111111111111111111\n");
 init_udp();
 
 
 
   /*Create a new decoder state in narrowband mode*/
   state = speex_decoder_init(&speex_nb_mode);

   /*Set the perceptual enhancement on*/
   tmp=1;
   speex_decoder_ctl(state, SPEEX_SET_ENH, &tmp);
   
   /*Initialization of the structure that holds the bits*/
   speex_bits_init(&bits);
       
  printf("222222222222\n");
/* Open PCM device for playback. */
 rc=snd_pcm_open(&handle,"default", SND_PCM_STREAM_PLAYBACK, 0);
 if (rc< 0) { fprintf(stderr,  "unable to open pcm device: %s\n",    snd_strerror(rc));
   exit(1); 
} 
 
/* Allocate a hardware parameters object. */
 snd_pcm_hw_params_alloca(&params); 
/* Fill it in with default values. */
 snd_pcm_hw_params_any(handle, params);
 /* Set the desired hardware parameters. */ 
/* Interleaved mode */ 
snd_pcm_hw_params_set_access(handle,params, SND_PCM_ACCESS_RW_INTERLEAVED); 
/* Signed 16-bit little-endian format */ 
snd_pcm_hw_params_set_format(handle,params, SND_PCM_FORMAT_S16_LE); 
/* Two channels (stereo) */  snd_pcm_hw_params_set_channels(handle, params, 1); 
/* 44100 bits/second sampling rate (CD quality) */ 
val = 8000; 
snd_pcm_hw_params_set_rate_near(handle,params,                                  &val, &dir);  /* Set period size to 32 frames. */ 
frames = 160; 
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);
/* Write the parameters to the driver */
 rc = snd_pcm_hw_params(handle, params);
 if (rc < 0) {   
fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc));   
exit(1); 
}
 /*Use a buffer large enough to hold one period*/
  snd_pcm_hw_params_get_period_size(params, &frames,  &dir); 
size = frames * 2;
/* 2 bytes/sample, 2 channels */ 
buffer = (char *) malloc(size); 
/* We want to loop for 5 seconds */
 snd_pcm_hw_params_get_period_time(params, &val, &dir); 
/* 5 seconds in microseconds divided by   * period time */
  loops = 5000000 / val;
 //while (loops > 0) {  
  while(1)
  {
   printf(".");
//loops--;  
//   rc = read(0, buffer, size); 
rc = recvfrom (fd, &cbits[0], 38, 0,&addr, &len);

//printf("rc=%d", rc);

   if (rc == 0) {   
      fprintf(stderr, "end of file on input\n");    
      break;   
}
else if (rc != 38) {     
fprintf(stderr, "short read: read %d bytes\n", rc);
     }   
     
     
     
      /*Read the "packet" encoded by sampleenc*/
      //fread(cbits, 1, nbBytes, fin[0]);
      
      
      /*Copy the data into the bit-stream struct*/
      speex_bits_read_from(&bits, cbits, 38);

      /*Decode the data*/
      speex_decode(state, &bits, output);

      /*Copy from float to short (16 bits) for output*/
      for (i=0;i<FRAME_SIZE;i++)
         out[i]=output[i];
              
rc = snd_pcm_writei(handle, out, frames);   
if (rc == -EPIPE) {    
  /* EPIPE means underrun */  
   fprintf(stderr, "underrun occurred\n");   
   snd_pcm_prepare(handle); 
  }
else if (rc < 0) {     
fprintf(stderr, "error from writei: %s\n",   snd_strerror(rc));  
 } 
else if (rc != (int)frames) {    
 fprintf(stderr, "short write, write %d frames\n", rc); 
 }
 } 
snd_pcm_drain(handle);
 snd_pcm_close(handle);
 free(buffer); 
return 0;
}

